import sys, os.path
from time import sleep
from threading import Thread
import numpy as np
from hiddev import extract_img

from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel
from PyQt5.QtCore import QTimer, QThread, pyqtSignal, QObject

from util.qt5 import ndarray2pixmap

from util.log import getLogger
logger = getLogger(10)

from common import *
from protocal import DpmDataTrans

HID_PACK_LEN = 64
BYTES_PACK_HEAD = bytes([0x80, 0x2e, 0x2e, 0x80])
BYTES_PACK_TAIL = bytes([0x2e, 0x80, 0x80, 0x2e])


class DpmRemoteTrans(DpmDataTrans, QObject):
    dataUpdated = pyqtSignal(np.ndarray)

    def __init__(self):
        super().__init__()
        QObject.__init__(self)

        self.bytes_recv = bytearray()

    def on_accept_data(self, data, addr):
        bytes_data = self.bytes_recv
        # pack = self.hid.read(HID_PACK_LEN, timeout_ms=BLOCK_TIMEOUT)
        pack = bytearray(data)

        index = pack.find(BYTES_PACK_TAIL)
        if index < 0:
            self.bytes_recv += pack
            return
        else:
            bytes_data += pack[:index+4]
            # BYTES_PACK_TAIL可能出现在两个64位包直接
            # 理应查找……这里直接忽略

        # 最大包长检测（如果一直未收到有效结束符）……忽略


        # check header
        if bytes_data and bytes_data[:4] != BYTES_PACK_HEAD:
            logger.debug(f"非法的HID数据头：【{bytes(bytes_data[:10])}】")
            # 舍弃数据
            self.bytes_recv = bytearray()
            return

            # 尝试二次查找有效数据……这里忽略
            # offset = bytes_data.find(BYTES_PACK_HEAD)
            # if offset > 0:
            #     logger.debug("已修复数据包")
            #     bytes_data = bytes_data[offset:]
            #     return bytes_data

        logger.debug(f"获取到HID数据，Length：【{len(bytes_data)}】")
        try:
            im_array = extract_img(bytes_data)
            self.dataUpdated.emit(im_array)
        except ValueError:
            # logger.debug(f"UDP数据丢失...")
            pass
        except Exception as e:
            logger.error(e)

        self.bytes_recv = bytearray()


class MainWnd(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(600, 400)
        self.setWindowTitle("HID图像传输")

        self._setup()
        self._setup_client()

    def _setup(self):
        mlayout = QVBoxLayout(self)
        self.lb_img = QLabel(self)
        self.lb_img.setScaledContents(True)
        mlayout.addWidget(self.lb_img)

    def _setup_client(self):
        from local import UdpClient

        self.client = UdpClient((BROKER_HOST, BROKER_PORT))
        protocal = DpmRemoteTrans()
        self.client.set_protocal(protocal)
        protocal.dataUpdated.connect(self.update_frame)
        self.client.start()

        # 查询当前协助列表
        protocal.register_list()
        protocal.connect_to_remote()

    def closeEvent(self, event):
        self.client.stop()
        self.client.join()
        self.client.destroy()
        logger.debug("Closing the Window...")

        super().closeEvent(event)

    def update_frame(self, im_array):
        pixmap = ndarray2pixmap(im_array)
        self.lb_img.setPixmap(pixmap)
